package org.etlt.job;

import org.etlt.SettingReader;
import org.etlt.load.Loader;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class JobExecution {

    private JobContext context;
    private List<ExecutionItem> executionItems = new ArrayList<>();

    public JobExecution(JobContext context) {
        this.context = context;
    }

    public void record(Loader player, int cost) {
        ExecutionItem item = new ExecutionItem();
        item.player = player.getName();
        item.playerType = player.getClass();
        item.status = player.getStatus().toString();
        item.cost = cost;
        int index = this.executionItems.indexOf(item);
        if (index != -1) {
            executionItems.set(index, item);
        } else
            executionItems.add(item);
    }

    public JobContext getContext() {
        return context;
    }

    public void setContext(JobContext context) {
        this.context = context;
    }

    public void record(Loader player) {
        record(player, -1);
    }

    public void doPersistence() throws IOException {
        File file = new File(getContext().getContextRoot(), getRecordName());
        SettingReader reader = new SettingReader();
        reader.write(new FileOutputStream(file), this.executionItems);
    }

    public void restore() throws IOException {
        File file = new File(getContext().getContextRoot(), getRecordName());
        if (file.exists()) {
            SettingReader reader = new SettingReader();
            this.executionItems = reader.read(new FileInputStream(file), List.class, ExecutionItem.class);
        }
    }

    private String getRecordName() {
        return
                getContext().getJobSetting().getName() + "." + JobContext.JOB_RECORD;
    }

    public List<ExecutionItem> getExecutionItems() {
        return executionItems;
    }

    @Override
    public String toString() {
        return "JobExecution{" +
                "executionItems=" + executionItems +
                '}';
    }

    public static class ExecutionItem {
        private String player;

        private Class<?> playerType;

        private String status;
        int cost;

        public String getPlayer() {
            return player;
        }

        public Class<?> getPlayerType() {
            return playerType;
        }

        public String getStatus() {
            return status;
        }

        @Override
        public boolean equals(Object other) {
            if (this == other) return true;
            if (other == null || getClass() != other.getClass()) return false;
            ExecutionItem item = (ExecutionItem) other;
            return Objects.equals(player, item.player) && Objects.equals(playerType, item.playerType);
        }

        @Override
        public int hashCode() {
            return Objects.hash(player, playerType);
        }

        @Override
        public String toString() {
            return "ExecutionItem{" +
                    "player='" + player + '\'' +
                    ", playerType=" + playerType +
                    ", status='" + status + '\'' +
                    '}';
        }
    }
}
